package net.lucode.hackware.magicindicatordemo.ext.navigator;

import net.lucode.hackware.magicindicator.abs.IPagerNavigator;
import net.lucode.hackware.magicindicator.buildins.UIUtil;
import ohos.agp.components.Component;
import ohos.agp.components.ComponentContainer;
import ohos.agp.render.Canvas;
import ohos.agp.render.Paint;
import ohos.agp.utils.Color;
import ohos.agp.utils.Point;
import ohos.app.Context;

import java.util.ArrayList;
import java.util.List;

/**
 * DummyCircleNavigator
 *
 * @since 2020-09-29
 */
public class DummyCircleNavigator extends Component implements IPagerNavigator,
        ComponentContainer.ArrangeListener, Component.DrawTask {
    private int mRadius;
    private int mCircleColor;
    private int mStrokeWidth;
    private int mCircleSpacing;
    private int mCircleCount;

    private int mCurrentIndex;
    private List<Point> mCirclePoints = new ArrayList<Point>();
    private Paint mPaint = new Paint();

    /**
     * DummyCircleNavigator
     *
     * @param context context
     */
    public DummyCircleNavigator(Context context) {
        super(context);
        mRadius = UIUtil.vp2px(context, 3);
        mCircleSpacing = UIUtil.vp2px(context, 8);
        mStrokeWidth = UIUtil.vp2px(context, 1);
        addDrawTask(this);
    }

    @Override
    public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
    }

    @Override
    public void onPageScrollStateChanged(int state) {
    }

    @Override
    public boolean onArrange(int i, int i1, int i2, int i3) {
        prepareCirclePoints();
        return false;
    }

    private void prepareCirclePoints() {
        mCirclePoints.clear();
        if (mCircleCount > 0) {
            int height = getHeight() / 2;
            int measureWidth = mCircleCount * mRadius * 2 + (mCircleCount - 1) * mCircleSpacing;
            int centerSpacing = mRadius * 2 + mCircleSpacing;
            int startX = (getWidth() - measureWidth) / 2 + mRadius;
            for (int index = 0; index < mCircleCount; index++) {
                Point pointF = new Point(startX, height);
                mCirclePoints.add(pointF);
                startX += centerSpacing;
            }
        }
    }

    @Override
    public void onDraw(Component component, Canvas canvas) {
        drawDeselectedCircles(canvas);
        drawSelectedCircle(canvas);
    }

    private void drawDeselectedCircles(Canvas canvas) {
        mPaint.setStyle(Paint.Style.STROKE_STYLE);
        mPaint.setStrokeWidth(mStrokeWidth);
        mPaint.setColor(new Color(mCircleColor));
        for (int index = 0, size = mCirclePoints.size(); index < size; index++) {
            Point pointF = mCirclePoints.get(index);
            canvas.drawCircle(pointF.getPointX(), pointF.getPointY(), mRadius, mPaint);
        }
    }

    private void drawSelectedCircle(Canvas canvas) {
        mPaint.setStyle(Paint.Style.FILL_STYLE);
        if (mCirclePoints.size() > 0) {
            float selectedCircleX = mCirclePoints.get(mCurrentIndex).getPointX();
            canvas.drawCircle(selectedCircleX, (float) getHeight() / 2, mRadius, mPaint);
        }
    }

    // 被添加到 magicindicator 时调用
    @Override
    public void onAttachToMagicIndicator() {
    }

    // 从 magicindicator 上移除时调用
    @Override
    public void onDetachFromMagicIndicator() {
    }

    // 当指示数目改变时调用
    @Override
    public void notifyDataSetChanged() {
        prepareCirclePoints();
        invalidate();
    }

    @Override
    public void onPageSelected(int position) {
        mCurrentIndex = position;
        invalidate();
    }

    /**
     * getCircleColor
     *
     * @return mCircleColor
     */
    public int getCircleColor() {
        return mCircleColor;
    }

    /**
     * setCircleColor
     *
     * @param circleColor circleColor
     */
    public void setCircleColor(int circleColor) {
        mCircleColor = circleColor;
        invalidate();
    }

    /**
     * getStrokeWidth
     *
     * @return mStrokeWidth
     */
    public int getStrokeWidth() {
        return mStrokeWidth;
    }

    /**
     * setStrokeWidth
     *
     * @param strokeWidth strokeWidth
     */
    public void setStrokeWidth(int strokeWidth) {
        mStrokeWidth = strokeWidth;
        invalidate();
    }

    /**
     * getRadius
     *
     * @return mRadius
     */
    public int getRadius() {
        return mRadius;
    }

    /**
     * setRadius
     *
     * @param radius radius
     */
    public void setRadius(int radius) {
        mRadius = radius;
        prepareCirclePoints();
        invalidate();
    }

    /**
     * getCircleSpacing
     *
     * @return mCircleSpacing
     */
    public int getCircleSpacing() {
        return mCircleSpacing;
    }

    /**
     * setCircleSpacing
     *
     * @param circleSpacing circleSpacing
     */
    public void setCircleSpacing(int circleSpacing) {
        mCircleSpacing = circleSpacing;
        prepareCirclePoints();
        invalidate();
    }

    /**
     * getCurrentIndex
     *
     * @return mCurrentIndex
     */
    public int getCurrentIndex() {
        return mCurrentIndex;
    }

    /**
     * getCircleCount
     *
     * @return mCircleCount
     */
    public int getCircleCount() {
        return mCircleCount;
    }

    /**
     * notifyDataSetChanged应该紧随其后调用
     *
     * @param circleCount circleCount
     */
    public void setCircleCount(int circleCount) {
        mCircleCount = circleCount;
    }
}
